1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.webmacro.servlet;
25
26 import org.webmacro.Broker;
27 import org.webmacro.InitException;
28 import org.webmacro.Log;
29 import org.webmacro.util.LogSystem;
30
31 import javax.servlet.Servlet;
32 import javax.servlet.ServletContext;
33 import java.io.InputStream;
34 import java.net.URL;
35 import java.util.Properties;
36
37 /***
38 * An implementation of Broker tailored for Servlet 2.0/2.1
39 * environments.
40 * <p>
41 * Loads templates and other resources from:
42 * <ol>
43 * <li> the class path,
44 * </p>
45 * writes log messages to the servlet log.
46 * @author Brian Goetz
47 * @author Marc Palmer (wj5@wangjammers.org)
48 * @since 0.96
49 */
50
51 public class Servlet20Broker extends ServletBroker
52 {
53
54 protected ClassLoader _servletClassLoader;
55
56 protected Servlet20Broker (ServletContext sc,
57 ClassLoader cl,
58 Properties additionalProperties) throws InitException
59 {
60 super(sc);
61 _servletClassLoader = cl;
62
63 String propertySource = WEBMACRO_DEFAULTS + ", " + WEBMACRO_PROPERTIES;
64 loadDefaultSettings();
65 loadSettings(WEBMACRO_PROPERTIES, true);
66 if (additionalProperties != null && additionalProperties.keySet().size() > 0)
67 {
68 propertySource += ", (additional Properties)";
69 loadSettings(additionalProperties);
70 }
71 propertySource += ", (System Properties)";
72 loadSystemSettings();
73 initLog(_config);
74
75 _log.notice("Loaded settings from " + propertySource);
76 init();
77 }
78
79 /***
80 * Get a Servlet API 2.0 compatible broker for the Servlet specified
81 * @param s The servlet
82 * @param additionalProperties
83 * @return The broker for the servlet context.
84 * @throws InitException
85 */
86 public static Broker getBroker (Servlet s, Properties additionalProperties) throws InitException
87 {
88 ServletContext sc = s.getServletConfig().getServletContext();
89 ClassLoader cl = s.getClass().getClassLoader();
90 return _getBroker(sc, cl, additionalProperties, true,
91 s.getClass().getName());
92 }
93
94 /***
95 * Get a Servlet API 2.0 compatible broker for the ServletContext specified
96 * @param sc The Servlet context
97 * @param cl A ClassLoader to use, presumably the webapp classloader
98 * @param additionalProperties
99 * @return The broker for the servlet context
100 * @throws InitException
101 * @since 2.1 JSDK
102 */
103 public static Broker getBroker (ServletContext sc, ClassLoader cl,
104 Properties additionalProperties) throws InitException
105 {
106 return _getBroker(sc, cl, additionalProperties, false, sc.toString() );
107 }
108
109 /***
110 * Get an existing instance of the Servlet 2.0/2.1 broker or create a new one.
111 * Templates will be retrieved relative to the ServletContext root
112 * and classes loaded from the ClassLoader passed in. NOTE: Templates
113 * will <b>not</b> be loaded from the classpath.
114 * @param sc The ServletContext to template access
115 * @param cl The ClassLoader for class loading, typically servlet or
116 * JSP page's class loader
117 * @param additionalProperties
118 * @param fromServlet true if it is actually an initialization derived from
119 * a Servlet instance passed in - just for nicer logging output
120 * @param servletOrContextName Name of the servlet or context originating this broker,
121 * for nicer logging
122 * @return The broker for the servlet context
123 * @throws org.webmacro.InitException
124 * @since 2.1 JSDK
125 */
126 protected static Broker _getBroker (ServletContext sc,
127 ClassLoader cl, Properties additionalProperties, boolean fromServlet,
128 String servletOrContextName) throws InitException
129 {
130 try
131 {
132 Object key = cl;
133 if (additionalProperties != null && additionalProperties.keySet().size() > 0)
134 key = new PropertiesPair(cl, additionalProperties);
135
136 Broker b = findBroker(key);
137 if (b == null)
138 {
139 b = new Servlet20Broker(sc, cl, additionalProperties);
140 register(key, b);
141 }
142 else
143 b.getLog("broker").notice(
144 (fromServlet ? "Servlet " : "ServletContext ")
145 + servletOrContextName
146 + " joining Broker" + " " + b.getName() );
147 return b;
148 }
149 catch (InitException e)
150 {
151 Log log = LogSystem.getSystemLog("wm");
152 log.error("Failed to initialized WebMacro from "+
153 (fromServlet ? "Servlet " : "ServletContext ")
154 + servletOrContextName);
155 throw e;
156 }
157 }
158
159 /***
160 * Get a resource (file) from the the Broker's class loader */
161 public URL getResource (String name)
162 {
163 URL u = _servletClassLoader.getResource(name);
164 if (u == null)
165 u = super.getResource(name);
166 return u;
167 }
168
169 /***
170 * Get a resource (file) from the Broker's class loader
171 */
172 public InputStream getResourceAsStream (String name)
173 {
174 InputStream is = _servletClassLoader.getResourceAsStream(name);
175 if (is == null)
176 is = super.getResourceAsStream(name);
177 return is;
178 }
179
180 /***
181 * Loads a class by name. Uses the servlet classloader to load the
182 * class. If the class is not found uses the Broker classForName
183 * implementation. */
184
185 public Class classForName (String name) throws ClassNotFoundException
186 {
187 Class cls = null;
188 try
189 {
190 cls = _servletClassLoader.loadClass(name);
191 }
192 catch (ClassNotFoundException e)
193 {
194 }
195
196 if (cls == null)
197 cls = super.classForName(name);
198
199 return cls;
200 }
201
202 }